#include "BFSSolver.h"

BFSSolver::BFSSolver(Node *root) : Solver(root)
{
}

void BFSSolver::solve(std::string order, std::string id_heuristic) {
	
	/*
	while (node->getLevel()<12){
	this->getNode();
	if (this->checkVisited()){
	continue;
	}
	if (node->getLevel() < 12){
	std::stringstream bf;
	bf << "ukladanki/u" << node->getLevel() << " " << files[node->getLevel()] << ".txt";
	std::ofstream out(bf.str());
	std::cout.rdbuf(out.rdbuf()); //redirect std::cout to out.txt!
	std::cout << 4 << " " << 4 << std::endl;
	node->showState();
	files[node->getLevel()]++;
	}
	this->createChildren(order);
	this->pushChildren();
	countNode++;
	if (maxDepth < node->getLevel()){
	maxDepth = node->getLevel();
	}
	}
	*/
	firstPush();

	std::string *order2;
	if (order.at(0) == 'R'){
		order2 = new std::string("LPGD");
	}
	else {
		order2 = new std::string(order);
	}
	while (!this->checkWinState()) {
		
		this->getNode();
		if (this->checkVisited()){
			continue;
		}
		if (order.at(0) == 'R'){
			this->randomOrder(order2);
		}
		this->createChildren(order2);
		this->pushChildren();
		countNode++;
		if (maxDepth < node->getLevel()){
			maxDepth = node->getLevel();
		}
	}
	std::string steps = findPath(node);
	std::cout << steps.size() << std::endl << steps;
}

void BFSSolver::firstPush(){
	queue.push(node);
}

void BFSSolver::getNode(){
	node = queue.front();
	queue.pop();
}

bool BFSSolver::checkVisited(){
	bool exist = false;

	for (int n = 0; n < visited.size(); n++) {
		if (compare(visited.at(n), node)) {
			exist = true;
			break;
		}
	}
	if (!exist)
		visited.push_back(node);

	return exist;
}

void BFSSolver::createChildren(std::string *order){
	for (int j = 0; j < order->size(); j++) {
		node->createChild(order->at(j));
	}
}

void BFSSolver::pushChildren(){
	for (int i = 0; i < node->getChildren()->size(); i++) {
		queue.push(node->getChildren()->at(i));
		countChildren++;
	}
}

BFSSolver::~BFSSolver()
{
}
